package api

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/olahol/melody"
	"net/http"
	"time"
	"yun_image/config/api"
	"yun_image/entity"
	"yun_image/service"
	"yun_image/util"
)

var m = melody.New()

func generateInfoMessage(session *melody.Session) *entity.SentInfoMessage {
	chatRoom := service.ChatService.GetChatRoomBySession(session)
	sessions := service.ChatService.GetSessionsByChatRoom(chatRoom)
	return &entity.SentInfoMessage{
		Count: len(sessions),
	}
}
func init() {
	m.HandleMessage(func(session *melody.Session, bytes []byte) {

		// 从websocket里提取信息，获取账号和聊天室
		var webSocketMessage = &entity.ReceivedMessage{}
		err := json.Unmarshal(bytes, webSocketMessage)
		if err != nil {
			return
		}
		account := util.UserTokenUtil.GetAccount(webSocketMessage.Token)
		chatRoom := service.ChatService.GetChatRoomById(webSocketMessage.ChatRoomId)
		if account == "" || chatRoom == nil {
			return
		}

		// 如果是刚刚建立连接，则更新用户session，并向聊天室内所有人发送聊天室信息
		if service.ChatService.GetSessionByUser(account) != session {
			service.ChatService.UpdateSession(account, session, chatRoom)
		}

		// 生成响应信息并发送
		var chatMessage = entity.SentChatMessage{
			Account: account,
			Time:    time.Now().UnixMilli(),
			Data:    webSocketMessage.Data,
		}
		sessions := service.ChatService.GetSessionsByChatRoom(chatRoom)
		jsonBytes, err := json.Marshal(&chatMessage)
		if err != nil {
			return
		}

		// type为1才是聊天信息，广播并存储下来
		if webSocketMessage.TypeId == 1 {
			service.ChatService.AddMessage(chatMessage, webSocketMessage.ChatRoomId)
			m.BroadcastMultiple(jsonBytes, sessions)
		}

		// 如果askInfo为true，则返回聊天室信息
		if webSocketMessage.AskInfo {
			jsonBytes, err = json.Marshal(generateInfoMessage(session))
			if err != nil {
				return
			}
			m.BroadcastMultiple(jsonBytes, sessions)
		}
	})
	// 释放连接时，并向聊天室内所有人发送聊天室信息，然后删除用户session
	m.HandleDisconnect(func(session *melody.Session) {
		chatRoom := service.ChatService.GetChatRoomBySession(session)
		sessions := service.ChatService.GetSessionsByChatRoom(chatRoom)
		infoMessage := generateInfoMessage(session)
		infoMessage.Count--
		jsonBytes, err := json.Marshal(infoMessage)
		if err != nil {
			return
		}
		m.BroadcastMultiple(jsonBytes, sessions)
		service.ChatService.RemoveSession(session)
	})
}
func wsChatRoom(context *gin.Context) {
	fmt.Println(util.Green("sttttt"))
	err := m.HandleRequest(context.Writer, context.Request)
	if err != nil {
		fmt.Println(util.Red(err.Error()))
	}

}

func createChatRoom(context *gin.Context) {
	userVal, _ := context.Get("user")
	user, _ := userVal.(entity.User)
	name := context.PostForm("name")
	if name == "" {
		context.String(http.StatusInternalServerError, "")
		return
	}
	chatRoom := service.ChatService.CreateChatRoom(user.Account, name)
	context.JSON(http.StatusOK, chatRoom)
}
func getChatRoomById(context *gin.Context) {
	id := context.PostForm("id")
	if id == "" {
		context.String(http.StatusInternalServerError, "")
		return
	}
	chatRoom := service.ChatService.GetChatRoomById(id)
	if chatRoom == nil {
		chatRoom = &entity.ChatRoom{}
	}
	context.JSON(http.StatusOK, chatRoom)
}
func getChatRooms(context *gin.Context) {
	userVal, _ := context.Get("user")
	user, _ := userVal.(entity.User)
	chatRooms := service.ChatService.GetChatRoomsByUser(user.Account)
	context.JSON(http.StatusOK, chatRooms)
}
func removeChatRoom(context *gin.Context) {
	userVal, _ := context.Get("user")
	user, _ := userVal.(entity.User)
	id := context.PostForm("id")
	chatRoom := service.ChatService.GetChatRoomById(id)

	if chatRoom == nil || chatRoom.HostAccount != user.Account {
		context.String(http.StatusInternalServerError, "")
		return
	}
	service.ChatService.RemoveChatRoom(id)
	context.JSON(http.StatusOK, gin.H{
		"success": true,
	})
}
func startChatRoomApi() {
	router.GET(api.WsChatRoomPath, wsChatRoom)
	router.POST(api.CreateChatRoomPath, createChatRoom)
	router.POST(api.GetChatRoomsPath, getChatRooms)
	router.POST(api.GetChatRoomByIdPath, getChatRoomById)
	router.POST(api.RemoveChatRoomPath, removeChatRoom)
}
